#include <Address.h>
#include <AddressException.h>
#include <Exception.h>
#include <IP.h>
#include <IPException.h>
#include <Socket.h>
#include <SocketException.h>
#include <SocketTCP.h>
#include <SocketUDP.h>
#include <Stats.h>
#include <StatsException.h>
#include <TransferCount.h>
#include <TransferCountException.h>
#include <HTTP.h>
#include <HTTPMessage.h>
#include <HTTPMessageGet.h>
#include <HTTPMessagePost.h>
#include <HTTPMessageResponse.h>
#include <uptimecl.h>
#include <types.h>

#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <string.h>
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <iostream.h>za

extern int errno;

int main(int argc, char *argv[])
{
    char uptimeHost[256];
    int uptimePort;
    char uptimeURL[512];
    char username[256];
    char pass[256];
    
    memset(uptimeHost, 0, sizeof(uptimeHost));
    memset(uptimeURL, 0, sizeof(uptimeURL));
    memset(username, 0, sizeof(username));
    memset(pass, 0, sizeof(pass));
    
    // Llegim el fitxer de configuracio
    char conffile[1024];
    memset(conffile, 0, sizeof(conffile));
    
    if (argc==1)
	sprintf(conffile, "uptime.conf");
    else
	sprintf(conffile, "%s", argv[1]);
    
    FILE *fd;
    fd=fopen(conffile, "r");
    
    if (fd==NULL)
    {
	printf("Cannot open config file %s\n", conffile);
	return -5;
    }
    
    char line[1024];
    char var[512];
    char value[512];
    char *p;
    while(!feof(fd))
    {
	memset(line, 0, sizeof(line));
	memset(var, 0, sizeof(var));
	memset(value, 0, sizeof(value));
	fgets(line, sizeof(line), fd);
	
	if (strlen(line)==0)
	    continue;

	p=strchr(line, '\n');
	*p=0;
	
	if (strlen(line)==0)
	    continue;
	
	if (line[0]=='#')
	    continue;
	
	p=strchr(line, '=');
	strncpy(value, p+1, 512);
	*p=0;
	strncpy(var, line, 512);
	
	
	if (strcmp(var, "server")==0)
	    strncpy(uptimeHost, value, sizeof(uptimeHost));
	else if (strcmp(var, "port")==0)
	    uptimePort=atoi(value);
	else if (strcmp(var, "path")==0)
	    strncpy(uptimeURL, value, sizeof(uptimeURL));
	else if (strcmp(var, "user")==0)
	    strncpy(username, value, sizeof(username));
	else if (strcmp(var, "pass")==0)
	    strncpy(pass, value, sizeof(pass));
	
    }
    
    fclose(fd);
    
    // Obtenim info amb uname(3)
    int res;
    struct utsname unameInfo;
    
    res=uname(&unameInfo);
    
    if (res!=0)
    {
	printf("\nuname call failed\n\n");
	return -1;
    }
    
    
    // Obtenim uptime a partir de sysctl(3) o de /proc/uptime
    long uptimeSecs;

#ifdef BSD
    struct timeval tBoot;
    struct timeval tAct;
    size_t strs=sizeof(struct timeval);    
    memset(&tBoot, 0, (int)strs);
    memset(&tAct, 0, (int)strs);
    
    int mib[2];
    
    mib[0]=CTL_KERN;
    mib[1]=KERN_BOOTTIME;
    
    res=sysctl(mib, 2, &tBoot, &strs, NULL, 0);
    
    if (res!=0)
    {
	printf("\nsysctl call failed. errno=%d.\n\n", errno);	
	return -2;
    }
    
    res=gettimeofday(&tAct, NULL);
    
    if (res!=0)
    {
	printf("\ngettimeofday call failed. errno=%d.\n\n", errno);	
	return -3;
    }
    
    uptimeSecs=tAct.tv_sec-tBoot.tv_sec;
#else
    FILE *fd2=fopen("/proc/uptime", "r");
    fscanf(fd2, "%u", &uptimeSecs);
    fclose(fd2);
  
#endif   
        
    

    
    // Construccio del missatge HTTP
    char cuptime[256];
    memset(cuptime, 0, sizeof(cuptime));
    sprintf(cuptime, "%d", uptimeSecs);

    
    HTTPMessagePost httpMsg(uptimeURL, HTTP_VERSION_1_0);
    
    httpMsg.addHdr("Host", uptimeHost);
    
    httpMsg.addVar("uptime", cuptime);
    httpMsg.addVar("sysname", unameInfo.sysname);
    httpMsg.addVar("nodename", unameInfo.nodename);
    httpMsg.addVar("release", unameInfo.release);
    httpMsg.addVar("version", unameInfo.version);
    httpMsg.addVar("machine", unameInfo.machine);
    httpMsg.addVar("username", username);
    httpMsg.addVar("pass", pass);
        
    HTTP *conHttp;
    try
    {
	IP ip(uptimeHost);
	Address addr(ip, uptimePort);
	conHttp=new HTTP(&addr);
	conHttp->connect();
    }
    catch (Exception e)
    {
	cout << e.getMsg() << endl;
	return -4;
    }
    
    conHttp->sendMessage(&httpMsg);
   
    HTTPMessageResponse httpResponse;    
    conHttp->recvMessage(&httpResponse);
    
    
    char bufContent[1024];
    memset(bufContent, 0, sizeof(bufContent));
    
    httpResponse.getData(bufContent, sizeof(bufContent));
    
    printf("%s\n", bufContent);
    
    delete conHttp;
    
    return 0;
}
